package com.cc.zk.config;

import com.cc.zk.ZkTemplate;
import com.cc.zk.distribute.idgen.IdGenerator;
import com.cc.zk.distribute.idgen.ZkSequenceIdGenerator;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

/**
 * 自动配置
 *
 * @author cc
 * @date 2022/08/24
 */
@Configuration
@ConditionalOnProperty(prefix = "zookeeper", name = "servers")
@EnableConfigurationProperties(value = ZkProperty.class)
public class ZkAutoConfiguration {


    /**
     * 获取 ZkSequenceIdGenerator 分布式ID 生成器
     */
    @Bean
    public IdGenerator zkSequenceIdGenerator() {
        return new ZkSequenceIdGenerator("demo");
    }


    /**
     * 初始化连接以及重试
     * @param zkProperty 配置属性
     * @return 连接
     */

    @Bean(initMethod = "start", destroyMethod = "close")
    @ConditionalOnMissingBean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public CuratorFramework curatorFramework(ZkProperty zkProperty) {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(zkProperty.getBaseSleepTime(), zkProperty.getMaxRetries());
        return CuratorFrameworkFactory.builder()
                .connectString(zkProperty.getServers())
                .connectionTimeoutMs(zkProperty.getConnectionTimeout())
                .sessionTimeoutMs(zkProperty.getSessionTimeout())
                .retryPolicy(retryPolicy)
                .build();
    }

    @Bean
    @ConditionalOnMissingBean
    public ZkTemplate zkTemplate(CuratorFramework curatorFramework) {
        return new ZkTemplate(curatorFramework);
    }


}
